#include "ManualObject.h"
#include "VertexDeclaration.h"
#include "BufferFactory.h"
#include "IRenderSystem.h"
#include "D3D9Mapping.h"
#include "Node.h"
#include "MD2Loader.h"
#include "ZIPManager.h"
#include "IFileRead.h"
#include "TextureFactory.h"
//
namespace Euclid
{
	ManualObject::ManualObject()
	{
		_type = "ManualObject";
		_bufferManager = BufferFactory::getSingletonPtr();
	}

	ManualObject::~ManualObject()
	{
		destroy();
	}

	bool ManualObject::create()
	{
		//
		POSITION_COLOR Vertices[] =
		{
			POSITION_COLOR(-1.0f,-1.0f, 0.0f, 0xffff0000), // x, y, z, rhw, color
			POSITION_COLOR( 1.0f,-1.0f, 0.0f, 0xff0000ff),
			POSITION_COLOR( 0.0f, 1.0f, 0.0f, 0xffffffff),
		};

		//
		_vb = _bufferManager->createVertexBuffer(3 * sizeof(POSITION_NORMAL),
			0, D3DPOOL_DEFAULT);

		//
		if (!_vb)
		{
			return false;
		}

		//
		Euclid::POSITION_COLOR* b = (Euclid::POSITION_COLOR*)_vb->lock(0, sizeof(Vertices), 0);

		//
		memcpy( b, Vertices, sizeof(Vertices) );

		//
		_vb->unLock();

		//
		return true;
	}

	void ManualObject::render()
	{
		_renderZPositive();
		_renderZNegative();
		_renderXPositive();
		_renderXNegative();
		_renderYPositive();
		_renderYNegative();
	}

	void ManualObject::preRender()
	{//
		//loader->preRender();
		if (_currentNode)
		{
			_renderSystem->setRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
			//
			_renderSystem->setRenderState(D3DRS_LIGHTING, false);
			//
			_currentNode->_updateFromParent();
			D3DXMATRIX m = D3D9Mapping::makeD3DXMatrix(_currentNode->_getFullTransform());
			_renderSystem->setWorldMatrix(&m);
		}
	}

	void ManualObject::postRender()
	{
		//loader->postRender();
		//
		_renderSystem->setVertexDeclaration(Euclid::VD_NULL);
		//
		D3DXMATRIX m = D3D9Mapping::makeD3DXMatrix(Euler::Matrix4::IDENTITY);
		_renderSystem->setWorldMatrix(&m);
	}

	void ManualObject::destroy()
	{
		if (_vb)
		{
			_vb->destroy();
		}
	}

	void ManualObject::_renderZPositive()
	{
		//
		POSITION_TEXTURE v[4] = 
		{
			POSITION_TEXTURE(-0.5f,  0.5f, 0.5f, 0.0f, 0.0f),
			POSITION_TEXTURE( 0.5f,  0.5f, 0.5f, 1.0f, 0.0f),
			POSITION_TEXTURE( 0.5f, -0.5f, 0.5f, 1.0f, 1.0f),
			POSITION_TEXTURE(-0.5f, -0.5f, 0.5f, 0.0f, 1.0f),
		};

		IFileRead* f = NULL;
		f = ZIPManager::getSingletonPtr()->getFileReader("posz.jpg");
		if (f == NULL)
		{
			return;
		}
		f->seek(0, false);
		unsigned char* buffer = new unsigned char[f->getSize()];
		f->read(buffer, f->getSize());

		static ITexture* tex = TextureFactory::getSingletonPtr()->createTexFromMemory(buffer, f->getSize());

		delete buffer;

		if (tex == NULL)
		{
			return;
		}

		_renderSystem->drawQuad(v, tex);
	}

	void ManualObject::_renderZNegative()
	{
		//
		POSITION_TEXTURE v[4] = 
		{
			POSITION_TEXTURE(-0.5f,  0.5f, -0.5f, 1.0f, 0.0f),
			POSITION_TEXTURE( 0.5f,  0.5f, -0.5f, 0.0f, 0.0f),
			POSITION_TEXTURE( 0.5f, -0.5f, -0.5f, 0.0f, 1.0f),
			POSITION_TEXTURE(-0.5f, -0.5f, -0.5f, 1.0f, 1.0f),
		};

		IFileRead* f = NULL;
		f = ZIPManager::getSingletonPtr()->getFileReader("negz.jpg");
		if (f == NULL)
		{
			return;
		}
		f->seek(0, false);
		unsigned char* buffer = new unsigned char[f->getSize()];
		f->read(buffer, f->getSize());

		static ITexture* tex = TextureFactory::getSingletonPtr()->createTexFromMemory(buffer, f->getSize());

		delete buffer;

		if (tex == NULL)
		{
			return;
		}

		_renderSystem->drawQuad(v, tex);
	}

	void ManualObject::_renderXPositive()
	{
		//
		POSITION_TEXTURE v[4] = 
		{
			POSITION_TEXTURE( 0.5f,  0.5f,  0.5f, 0.0f, 0.0f),
			POSITION_TEXTURE( 0.5f,  0.5f, -0.5f, 1.0f, 0.0f),
			POSITION_TEXTURE( 0.5f, -0.5f, -0.5f, 1.0f, 1.0f),
			POSITION_TEXTURE( 0.5f, -0.5f,  0.5f, 0.0f, 1.0f),
		};

		IFileRead* f = NULL;
		f = ZIPManager::getSingletonPtr()->getFileReader("posx.jpg");
		if (f == NULL)
		{
			return;
		}
		f->seek(0, false);
		unsigned char* buffer = new unsigned char[f->getSize()];
		f->read(buffer, f->getSize());

		static ITexture* tex = TextureFactory::getSingletonPtr()->createTexFromMemory(buffer, f->getSize());

		delete buffer;

		if (tex == NULL)
		{
			return;
		}

		_renderSystem->drawQuad(v, tex);
	}

	void ManualObject::_renderXNegative()
	{
		//
		POSITION_TEXTURE v[4] = 
		{
			POSITION_TEXTURE( -0.5f,  0.5f,  0.5f, 1.0f, 0.0f),
			POSITION_TEXTURE( -0.5f,  0.5f, -0.5f, 0.0f, 0.0f),
			POSITION_TEXTURE( -0.5f, -0.5f, -0.5f, 0.0f, 1.0f),
			POSITION_TEXTURE( -0.5f, -0.5f,  0.5f, 1.0f, 1.0f),
		};

		IFileRead* f = NULL;
		f = ZIPManager::getSingletonPtr()->getFileReader("negx.jpg");
		if (f == NULL)
		{
			return;
		}
		f->seek(0, false);
		unsigned char* buffer = new unsigned char[f->getSize()];
		f->read(buffer, f->getSize());

		static ITexture* tex = TextureFactory::getSingletonPtr()->createTexFromMemory(buffer, f->getSize());

		delete buffer;

		if (tex == NULL)
		{
			return;
		}

		_renderSystem->drawQuad(v, tex);
	}

	void ManualObject::_renderYPositive()
	{
		//
		POSITION_TEXTURE v[4] = 
		{
			POSITION_TEXTURE( -0.5f, 0.5f,  0.5f, 0.0f, 1.0f),
			POSITION_TEXTURE(  0.5f, 0.5f,  0.5f, 1.0f, 1.0f),
			POSITION_TEXTURE(  0.5f, 0.5f, -0.5f, 1.0f, 0.0f),
			POSITION_TEXTURE( -0.5f, 0.5f, -0.5f, 0.0f, 0.0f),
		};

		IFileRead* f = NULL;
		f = ZIPManager::getSingletonPtr()->getFileReader("posy.jpg");
		if (f == NULL)
		{
			return;
		}
		f->seek(0, false);
		unsigned char* buffer = new unsigned char[f->getSize()];
		f->read(buffer, f->getSize());

		static ITexture* tex = TextureFactory::getSingletonPtr()->createTexFromMemory(buffer, f->getSize());

		delete buffer;

		if (tex == NULL)
		{
			return;
		}

		_renderSystem->drawQuad(v, tex);
	}

	void ManualObject::_renderYNegative()
	{
		//
		POSITION_TEXTURE v[4] = 
		{
			POSITION_TEXTURE( -0.5f, -0.5f,  0.5f, 0.0f, 0.0f),
			POSITION_TEXTURE(  0.5f, -0.5f,  0.5f, 1.0f, 0.0f),
			POSITION_TEXTURE(  0.5f, -0.5f, -0.5f, 1.0f, 1.0f),
			POSITION_TEXTURE( -0.5f, -0.5f, -0.5f, 0.0f, 1.0f),
		};

		IFileRead* f = NULL;
		f = ZIPManager::getSingletonPtr()->getFileReader("negy.jpg");
		if (f == NULL)
		{
			return;
		}
		f->seek(0, false);
		unsigned char* buffer = new unsigned char[f->getSize()];
		f->read(buffer, f->getSize());

		static ITexture* tex = TextureFactory::getSingletonPtr()->createTexFromMemory(buffer, f->getSize());

		delete buffer;

		if (tex == NULL)
		{
			return;
		}

		_renderSystem->drawQuad(v, tex);
	}
}
